package com.gmlive.plugin.jenkins

import com.google.gson.Gson
import okhttp3.FormBody
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import java.util.concurrent.atomic.AtomicBoolean

/**
 * author: fanfeiyue
 * time: 2020/10/29
 * des:
 */
object DingTalkUtils {

    @JvmStatic
    fun sendDingBuildApkMsg(
        apkUrl: String,
        originApkUrl: String,
        aabUrl: String,
        extractApks: String,
        mappingUrl: String,
        apmMethodMappingUrl: String,
        obscureMappingUrl: String,
        resGuardResMappingUrl: String,
        apkMD5: String,
        apkSize: String,
        hotfixConfigUrl: String,
        patchUrl: String,
        jenkinsOptions: JenkinsOptions,
        jenkinsConfig: JenkinsExtension
    ) {
        val client = OkHttpClient()
        val apkBuildInfo = ApkBuildInfo(
            appName = jenkinsOptions.buildName,
            branch = jenkinsOptions.buildBranch,
            buildID = jenkinsOptions.buildId,
            buildUrl = jenkinsOptions.buildUrl,
            buildUser = jenkinsOptions.buildUser,
            apkUrl = apkUrl,
            originApkUrl = originApkUrl,
            changesCommitUrl = "${jenkinsOptions.buildUrl}${jenkinsOptions.buildId}/changes",
            apkMD5 = apkMD5,
            apkSize = apkSize,
            mappingUrl = mappingUrl,
            apmMethodMappingUrl = apmMethodMappingUrl,
            obscureMappingUrl = obscureMappingUrl,
            resGuardResMappingUrl = resGuardResMappingUrl,
            hotfixConfigUrl = hotfixConfigUrl,
            patchUrl = patchUrl,
            versionName = jenkinsOptions.versionName,
            userReinforce = jenkinsOptions.useReinforce,
            useBundle = jenkinsOptions.useBundle,
            uploadFir = jenkinsOptions.uploadFir,
            firAddress = jenkinsConfig.firApiUrl,
            buildDesc = jenkinsOptions.buildDesc,
            aabUrl = aabUrl,
            extractApks = extractApks,
            channel = jenkinsOptions.buildChannel
        )

        val paramStr = Gson().toJson(
            buildDingMsgModel(
                apkBuildInfo = apkBuildInfo,
                title = jenkinsConfig.dingTalkTitle,
                atMobiles = getAtMobiles(jenkinsOptions.atMobilesStr)
            )
        )

        println("[Jenkins] dingTalkSend：$paramStr")

        val body = FormBody.create(MediaType.parse("application/json; charset=utf-8"), paramStr)

        val request = Request.Builder()
            .url("https://oapi.dingtalk.com/robot/send?access_token=${jenkinsConfig.dingTalkToken}")
            .post(body)
            .build()

        val response = client.newCall(request).execute()

        println("[Jenkins] dingTalkSend ${response.body()?.string()}")
    }

    private fun getAtMobiles(atMobilesStr: String): List<String> {
        return atMobilesStr.replace('；', ';')
            .split(';')
            .map { it.trim() }
            .filter { it.isNotBlank() }
    }

    private fun buildDingMsgModel(
        apkBuildInfo: ApkBuildInfo,
        title: String = "",
        atMobiles: List<String> = listOf(),
        isAtAll: Boolean = false
    ): DingMsgModel {

        val markdown = Action(
            title = title,
            text = buildActionMsgText(apkBuildInfo, atMobiles),
        )

        val at = At(
            atMobiles = atMobiles,
            isAtAll = isAtAll
        )

        return DingMsgModel(
            msgtype = "markdown",
            markdown = markdown,
            at = at
        )

    }

    private fun buildActionMsgText(
        apkBuildInfo: ApkBuildInfo,
        atMobiles: List<String> = listOf()
    ): String {
        return apkBuildInfo.run {
            StringBuilder().apply {
                takeIf { !appName.isNullOrBlank() }?.let { append("### App: $appName").append("\n") }
                takeIf { !channel.isNullOrBlank() }?.let { append("- 渠道: $channel").append("\n") }
                takeIf { !branch.isNullOrBlank() }?.let { append("- 分支: $branch").append("\n") }
                takeIf { !buildUrl.isNullOrBlank() }?.let {
                    append("- JOB ID: [#$buildID](${buildUrl}${buildID}/)").append(
                        "\n"
                    )
                }
                takeIf { !buildUser.isNullOrBlank() }?.let { append("- 操作人: $buildUser").append("\n") }
                takeIf { !originApkUrl.isNullOrBlank() }?.let {
                    append("- 未加固包下载: [点击下载]($originApkUrl)").append(
                        "\n"
                    )
                }
                takeIf { !apkUrl.isNullOrBlank() }?.let {
                    append("- apk下载: [点击下载]($apkUrl)").append(
                        "\n"
                    )
                }
                takeIf { !aabUrl.isNullOrBlank() }?.let {
                    append("- aab下载: [点击下载]($aabUrl)").append(
                        "\n"
                    )
                }
                takeIf { !changesCommitUrl.isNullOrBlank() }?.let {
                    append("- 提交记录: [点击查看]($changesCommitUrl)").append(
                        "\n"
                    )
                }
                takeIf { !hotfixConfigUrl.isNullOrBlank() }?.let {
                    append("- HotfixConfig下载: [点击下载]($hotfixConfigUrl)").append(
                        "\n"
                    )
                }
                takeIf { !patchUrl.isNullOrBlank() }?.let {
                    append(
                        "- patch下载: [${
                            patchUrl?.split(
                                '/'
                            )?.lastOrNull() ?: "点击下载"
                        }]($patchUrl)"
                    ).append("\n")
                }
                takeIf { !apkMD5.isNullOrBlank() }?.let { append("- md5: $apkMD5").append("\n") }
                takeIf { !apkSize.isNullOrBlank() }?.let { append("- size: $apkSize").append("\n") }
                takeIf { !mappingUrl.isNullOrBlank() }?.let {
                    append("- mapping: $mappingUrl").append("\n")
                }
                takeIf { !apmMethodMappingUrl.isNullOrBlank() }?.let {
                    append("- methodMapping: $apmMethodMappingUrl").append("\n")
                }
                takeIf { !obscureMappingUrl.isNullOrBlank() }?.let {
                    append("- obscureMapping: $obscureMappingUrl").append("\n")
                }
                takeIf { !resGuardResMappingUrl.isNullOrBlank() }?.let {
                    append("- resGuardResMapping: $resGuardResMappingUrl").append("\n")
                }
                takeIf { !originApkUrl.isNullOrBlank() }?.let {
                    append("- 未加固包地址: $originApkUrl").append(
                        "\n"
                    )
                }
                takeIf { !apkUrl.isNullOrBlank() }?.let { append("- apk下载地址: $apkUrl").append("\n") }
                takeIf { !aabUrl.isNullOrBlank() }?.let { append("- aab下载地址: $aabUrl").append("\n") }
                takeIf { !extractApks.isNullOrBlank() }?.let {
                    append("- aab提取包地址: $extractApks").append("\n")
                }
                takeIf { !versionName.isNullOrBlank() }?.let {
                    append("- version: $versionName").append("\n")
                }
                takeIf { uploadFir && !firAddress.isNullOrBlank() }?.let {
                    append("- Fir地址: $firAddress").append("\n")
                }
                append("- 是否加固: $userReinforce").append("\n")
                append("\n")
                takeIf { !atMobiles.isNullOrEmpty() }?.let {
                    append("<font color=#1890ff face=\"黑体\">")

                    atMobiles.forEach {
                        append("@$it")
                    }

                    append("</font>")
                }

                takeIf { !buildDesc.isNullOrBlank() }?.let {
                    append("<font color=#000000 face=\"黑体\">")
                    append(buildDesc)
                    append("</font>")
                    append("\n")
                }

            }.toString()
        }
    }

}